import { app, ipcMain, shell } from 'electron'
import type { IpcMainInvokeEvent } from 'electron'
import fsExtra from 'fs-extra'
import path from 'node:path'
import nodePath from 'node:path'

/**
 * 将文件/文件夹路径,转化为 table 数据
 *    如果 flag 为 file, paths 中若存在目录,则读取目录下所有文件
 *    如果 flag 为 folder, paths 中若存在文件,则忽略
 */
ipcMain.handle(
  'convertPathsToTableData',
  async (
    _event: IpcMainInvokeEvent,
    pathList: string[],
    flag: 'file' | 'folder'
  ): Promise<ITableDataItem[]> => {
    const allPath: IPathResult[] = []

    if (flag === 'file') {
      for (const path of pathList) {
        await filesPathDisplay(path, allPath)
      }
    } else {
      for (const path of pathList) {
        await foldersPathDisplay(path, allPath)
      }
    }

    return convertPathToTableData(allPath)
  }
)

/**
 * 将文件/文件夹路径,转化为 table 数据
 */
export function convertPathToTableData(arr: IPathResult[]): ITableDataItem[] {
  const tableData: ITableDataItem[] = []

  for (const item of arr) {
    const res = nodePath.parse(item.fullPath)
    const tableDateItem: ITableDataItem = {
      // 文件 / 目录
      type: item.type,
      original: {
        name: res.name,
        ext: undefined
      },
      newest: {
        name: res.name,
        ext: undefined
      },
      path: res.dir,
      fullPath: item.fullPath,
      createTimeMs: item.createTimeMs,
      updateTimeMs: item.updateTimeMs,
      state: '10'
    }

    // 某些文件可能没有后缀
    if (res.ext.trim() !== '') {
      // 去除 .
      tableDateItem.original.ext = res.ext.slice(1)
      tableDateItem.newest.ext = res.ext.slice(1)
    }

    tableData.push(tableDateItem)
  }

  return tableData
}

/**
 * 接收一个路径
 *    若该路径指向一个目录,则返回该目录下的所有文件及子文件的路径
 *    若该路径指向一个文件,则返回该文件路径
 * @param basicPath 文件/目录的路径
 * @param arr 返回的结果集
 */
async function filesPathDisplay(basicPath: string, arr: IPathResult[]) {
  const res = await fsExtra.stat(basicPath)

  // 如果为目录
  if (res.isDirectory()) {
    const paths = await fsExtra.readdir(basicPath)
    for (const path of paths) {
      // 完整路径
      const fullPath = nodePath.join(basicPath, path)
      await filesPathDisplay(fullPath, arr)
    }
  } else {
    arr.push({
      type: 'file',
      fullPath: basicPath,
      createTimeMs: res.birthtimeMs,
      updateTimeMs: res.mtimeMs
    })
  }

  return arr
}

/**
 * 接收一个路径
 *    若该路径指向一个目录,则返回该路径
 *    若该路径指向一个文件,则忽略
 * @param basicPath 文件/目录的路径
 * @param arr 返回的结果集
 */
async function foldersPathDisplay(basicPath: string, arr: IPathResult[]) {
  const res = await fsExtra.stat(basicPath)

  if (res.isDirectory()) {
    arr.push({
      type: 'folder',
      fullPath: basicPath,
      createTimeMs: res.birthtimeMs,
      updateTimeMs: res.mtimeMs
    })
  }

  return arr
}

/**
 * 打开本机指定路径
 */
ipcMain.handle('openPath', (_event: IpcMainInvokeEvent, path: string) => {
  return shell.openPath(path)
})

/**
 * 确保目录一定存在,如果不存在则创建
 */
ipcMain.handle(
  'ensureDir',
  async (_event: IpcMainInvokeEvent, dirPath: string) => {
    await fsExtra.ensureDir(dirPath)
  }
)

/**
 * 获取 target 目录
 */
ipcMain.handle('getAppSaveDir', async () => {
  const desktopPath = app.getPath('desktop')
  const targetDir = path.join(desktopPath, '批量重命名软件')
  await fsExtra.ensureDir(targetDir)
  return targetDir
})
